package com.cloud.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * jwt令牌工具类
 */
public class JwtUtil {

    // 令牌密钥
    private static final String secret = "93ce7d0a67884ab9c61a841f5177ad0aAd32Bd209bae992bc9defBaa1c74efe26c3e8";

    /**
     * 生成jwt令牌
     * @param info 存入jwt令牌中的数据
     * @param effectiveTimeMills 过期时间，若小于0则不限制过期时间，单位为毫秒
     * @return jwt令牌
     * @param <T> 存入jwt中的java对象
     * @throws JsonProcessingException json与java对象之间的转换异常
     */
    public static <T> String generateJwt(T info, long effectiveTimeMills) throws JsonProcessingException {

        HashMap<String, Object> claims = MappingUtil.ObjectToMap(info);
        Date expirationTime = new Date(System.currentTimeMillis() + effectiveTimeMills);

        if (effectiveTimeMills > 0) {
            return Jwts.builder()
                    .setClaims(claims)
                    .signWith(SignatureAlgorithm.HS512, secret)         // 使用HS512算法和密钥签名
                    .setExpiration(expirationTime)                      // 设置过期时间
                    .compact();                                         // 生成并返回紧凑形式的JWT字符串间
        }

        return Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret)         // 使用HS512算法和密钥签名
                .compact();                                         // 生成并返回紧凑形式的JWT字符串间

    }

    /**
     * 解析jwt令牌
     * @param jwt jwt令牌
     * @param clazz 解析后用来接受jwt中数据的类型
     * @return jwt中的数据
     * @param <T> 接受数据的java对象
     * @throws JsonProcessingException json与java对象之间的转换异常
     */
    public static <T> T parseJwt(String jwt , Class<T> clazz) throws JsonProcessingException  {
        Map<String, Object> claims = Jwts.parser()
                .setSigningKey(secret)                              // 使用与生成时相同的密钥来验证签名
                .parseClaimsJws(jwt)                                // 解析JWT并验证签名
                .getBody();
        return MappingUtil.MapToObject(claims, clazz);
    }

}
